<template>
  <div class="source-manager">
    <!-- 顶部操作栏 -->
    <page-header title="素材库" :subtitle="`${totalCount} 个文件`">
      <template #right>
        <div class="header-actions">
          <!-- 搜索框 -->
          <div class="search-box">
            <el-input
              v-model="searchKeyword"
              placeholder="搜索文件名称"
              clearable
              @input="debounceSearch"
              @clear="handleResetKeyword"
            >
              <template #prefix>
                <el-icon><Search /></el-icon>
              </template>
            </el-input>
          </div>

          <div class="view-switch">
            <el-radio-group v-model="viewMode" size="large">
              <el-radio-button :value="'grid'">
                <el-icon><Grid /></el-icon>
              </el-radio-button>
              <el-radio-button :value="'list'">
                <el-icon><List /></el-icon>
              </el-radio-button>
            </el-radio-group>
          </div>

          <el-button
            type="primary"
            class="upload-btn"
            size="small"
            @click="showUploadDialog = true"
          >
            <el-icon><Upload /></el-icon>
            <span>上传文件</span>
          </el-button>
        </div>
      </template>
    </page-header>

    <!-- 批量操作栏 -->
    <BatchActionBar
      v-if="viewMode === 'list'"
      :selectedCount="selectedItems.length"
      @batchDelete="handleBatchDelete"
      @batchMove="handleBatchMove"
    />

    <!-- 移动分组对话框 -->
    <el-dialog
      v-model="showMoveGroupDialog"
      title="移动到分组"
      width="500px"
      :close-on-click-modal="false"
      @open="onMoveDialogOpen"
    >
      <div class="move-group-dialog">
        <p class="dialog-tip">选择要移动到的分组：</p>
        <div class="group-grid">
          <el-radio-group v-model="targetGroupId" class="group-list">
            <el-radio
              v-for="group in mediaGroups"
              :key="group.id"
              :label="String(group.id)"
              class="group-item"
            >
              <div class="group-content">
                <div class="group-info">
                  <el-icon><Folder /></el-icon>
                  <span class="group-name">{{ group.name }}</span>
                  <el-tooltip
                    v-if="group.description"
                    :content="group.description"
                    placement="top"
                    effect="light"
                    :show-after="300"
                  >
                    <el-icon class="info-icon"><InfoFilled /></el-icon>
                  </el-tooltip>
                </div>
                <div class="group-actions">
                  <span class="count">{{ getGroupCount(group.id) }}</span>
                </div>
              </div>
            </el-radio>
          </el-radio-group>
        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="showMoveGroupDialog = false">取消</el-button>
          <el-button type="primary" @click="confirmMoveToGroup">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 上传文件对话框 -->
    <el-dialog
      v-model="showUploadDialog"
      title="上传文件"
      width="500px"
      :close-on-click-modal="false"
      @closed="cancelUpload"
    >
      <div class="upload-dialog">
        <el-upload
          ref="uploadRef"
          class="upload-area"
          drag
          action="#"
          :auto-upload="false"
          :show-file-list="true"
          :on-change="handleFileSelected"
          :on-remove="handleFileRemove"
          multiple
        >
          <el-icon class="upload-icon"><Upload /></el-icon>
          <div class="upload-text">
            <p>拖放文件到此处或点击选择文件</p>
            <p class="upload-tip">支持上传各种类型的素材文件</p>
          </div>
        </el-upload>

        <div class="upload-options" v-if="selectedFiles.length > 0">
          <div class="option-item">
            <span class="option-label">选择分组：</span>
            <el-select v-model="uploadGroupId" placeholder="选择分组">
              <el-option key="-1" label="未分组" :value="'-1'" />
              <el-option
                v-for="group in mediaGroups.filter((g) => g.id !== '-1')"
                :key="group.id"
                :label="group.name"
                :value="group.id"
              />
            </el-select>
          </div>
        </div>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancelUpload">取消</el-button>
          <el-button type="primary" :disabled="!selectedFiles.length" @click="confirmUpload">
            上传 ({{ selectedFiles.length }} 个文件)
          </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 编辑分组对话框 -->
    <el-dialog
      v-model="showEditGroupDialog"
      title="编辑分组"
      width="400px"
      :close-on-click-modal="false"
    >
      <div class="edit-group-dialog">
        <el-form :model="currentEditGroup" :rules="rules" ref="formRef" label-position="top">
          <el-form-item label="分组名称" prop="name">
            <el-input v-model="currentEditGroup.name" />
          </el-form-item>
          <el-form-item label="描述信息" prop="description">
            <el-input v-model="currentEditGroup.description" type="textarea" :rows="3" />
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <div>
            <el-button
              v-if="currentEditGroup && currentEditGroup.id !== '-1' && currentEditGroup.id !== '1'"
              type="danger"
              @click="handleDeleteGroup"
              class="delete-btn"
            >
              删除分组
            </el-button>
          </div>
          <div>
            <el-button @click="showEditGroupDialog = false">取消</el-button>
            <el-button type="primary" @click="confirmEditGroup">确定</el-button>
          </div>
        </div>
      </template>
    </el-dialog>

    <!-- 新建分组弹窗 -->
    <el-dialog
      v-model="showAddGroupDialog"
      title="新建分组"
      width="400px"
      :close-on-click-modal="false"
    >
      <div class="add-group-dialog">
        <el-form :model="newGroupForm" :rules="rules" ref="addGroupFormRef" label-position="top">
          <el-form-item label="分组名称" prop="name">
            <el-input v-model="newGroupForm.name" placeholder="请输入分组名称" />
          </el-form-item>
          <el-form-item label="描述信息" prop="description">
            <el-input
              v-model="newGroupForm.description"
              type="textarea"
              :rows="3"
              placeholder="请输入描述信息（选填）"
            />
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="showAddGroupDialog = false">取消</el-button>
          <el-button type="primary" @click="submitAddGroup">确定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 主内容区 -->
    <div class="main-content">
      <!-- 左侧分组导航 -->
      <SidebarFilter
        class="sidebar"
        :activeType="activeType"
        :activeGroup="activeGroup"
        :sortBy="sortBy"
        :mediaGroups="mediaGroups"
        :mediaList="mediaList"
        ref="sidebarFilterRef"
        @typeChange="handleTypeChange"
        @groupChange="handleGroupChange"
        @sortChange="handleSortChange"
        @addGroup="handleAddGroup"
        @editGroup="handleEditGroup"
      />

      <!-- 右侧内容展示区 -->
      <div class="content">
        <el-scrollbar>
          <!-- 加载状态 -->
          <div v-if="loading" class="loading-container">
            <el-empty description="加载中..." :image-size="60">
              <template #image>
                <el-icon class="loading-icon"><Loading /></el-icon>
              </template>
            </el-empty>
          </div>

          <!-- 空数据状态 -->
          <div v-else-if="filteredMediaList.length === 0" class="empty-container">
            <el-empty description="暂无素材，请上传">
              <el-button type="primary" @click="showUploadDialog = true">
                <el-icon><Upload /></el-icon> 上传文件
              </el-button>
            </el-empty>
          </div>

          <!-- 网格视图 -->
          <MediaGrid
            v-else-if="viewMode === 'grid'"
            :mediaFiles="currentPageData"
            @copyLink="handleCopyLink"
            @delete="handleDeleteMedia"
            @preview="handleImagePreview"
            @itemClick="handleItemClick"
            @moveGroup="handleMoveMedia"
          />

          <!-- 列表视图 -->
          <MediaList
            v-else
            :mediaFiles="currentPageData"
            @selectionChange="handleSelectionChange"
            @copyLink="handleCopyLink"
            @delete="handleDeleteMedia"
            @preview="handleImagePreview"
            @itemClick="handleItemClick"
          />
        </el-scrollbar>

        <!-- 分页器 -->
        <div class="pagination" v-if="filteredMediaList.length > 0">
          <el-pagination
            v-model:current-page="currentPage"
            v-model:page-size="pageSize"
            :total="totalCount"
            :page-sizes="[12, 24, 36, 48]"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
/**
 * 素材库管理组件
 *
 * 功能：
 * 1. 媒体文件的上传、预览、删除和管理
 * 2. 文件分组显示与管理
 * 3. 文件筛选、排序和搜索
 * 4. 网格/列表视图切换
 * 5. 支持批量操作
 */
import { ref, computed, onMounted, h, nextTick } from 'vue'
import { ElMessageBox, ElMessage, ElLoading, ElForm, ElFormItem, ElInput } from 'element-plus'
import type { UploadFile } from 'element-plus'
import { Grid, List, Upload, Folder, Loading, InfoFilled, Search } from '@element-plus/icons-vue'
import PageHeader from '@/components/PageHeader/index.vue'

// 导入拆分的组件
import SidebarFilter from './components/SidebarFilter.vue'
import MediaGrid from './components/MediaGrid.vue'
import MediaList from './components/MediaList.vue'
import BatchActionBar from './components/BatchActionBar.vue'
import SearchDialog from './components/SearchDialog.vue'

// 导入工具函数和类型定义
import {
  sortMediaList,
  formatTime,
  generateMarkdownLink,
  copyToClipboard,
} from '@/utils/mediaUtils'

// 导入API
import { sourceApi } from '@/api/source'

// =============== 工具函数 ===============

/**
 * 防抖函数
 */
function useDebounce(fn, delay = 300) {
  let timer = null
  return function (...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

// =============== 状态定义 ===============

/**
 * 搜索和筛选状态
 */
const searchKeyword = ref('')
const activeType = ref('all')
const activeGroup = ref(null)
const viewMode = ref('grid')
const sortBy = ref('time')
const sortOrder = ref('descend')
const selectedItems = ref([])
const showSearchPanel = ref(false)

/**
 * 分页状态
 */
const currentPage = ref(1)
const pageSize = ref(12)
const totalCount = ref(0) // 总记录数

/**
 * 分组数据
 * 定义媒体文件的分组信息
 */
const mediaGroups = ref([
  { id: '-1', name: '未分组', description: '默认分组，未分类的文件' },
  { id: '2', name: '博客配图', description: '博客文章使用的配图' },
  { id: '3', name: '文档资料', description: '各类文档资料' },
])

/**
 * 媒体文件数据
 * 模拟数据，实际应从API获取
 */
const mediaList = ref([
  {
    id: 1,
    name: 'banner.jpg',
    type: 'image',
    url: 'https://picsum.photos/800/400',
    size: '1.2MB',
    updateTime: '2024/3/20 12:00:00',
    groupId: '2',
  },
  {
    id: 2,
    name: 'documentation.pdf',
    type: 'document',
    url: '#',
    size: '2.5MB',
    updateTime: '2024/3/19 15:30:00',
    groupId: '-1',
  },
  {
    id: 3,
    name: 'profile.jpg',
    type: 'image',
    url: 'https://picsum.photos/600/600',
    size: '0.8MB',
    updateTime: '2024/3/18 09:15:00',
    groupId: '2',
  },
  {
    id: 4,
    name: 'report.doc',
    type: 'document',
    url: '#',
    size: '1.8MB',
    updateTime: '2024/3/17 14:00:00',
    groupId: '3',
  },
])

/**
 * 移动分组状态
 */
const showMoveGroupDialog = ref(false)
const currentMoveItem = ref(null)
const targetGroupId = ref('-1')

/**
 * 上传文件状态
 */
const showUploadDialog = ref(false)
const selectedFiles = ref<UploadFile[]>([])
const uploadGroupId = ref<string>('-1')
const uploadRef = ref() // 添加对上传组件的引用

/**
 * 编辑分组对话框状态
 */
const showEditGroupDialog = ref(false)
const currentEditGroup = ref(null)

/**
 * 新建分组对话框状态
 */
const showAddGroupDialog = ref(false)
const newGroupForm = ref({
  name: '',
  description: '',
})

// 添加表单引用
const addGroupFormRef = ref()

// 添加引用
const sidebarFilterRef = ref(null)

// =============== 计算属性 ===============

/**
 * 经过筛选的媒体列表
 * 根据搜索关键词、文件类型和分组进行筛选
 */
const filteredMediaList = computed(() => {
  // 直接返回API加载的数据，因为筛选已在API中处理
  return mediaList.value
})

/**
 * 当前页的数据
 * 根据分页参数计算当前页显示的数据
 */
const currentPageData = computed(() => {
  // 直接返回API加载的数据，因为分页已在API中处理
  return mediaList.value
})

// =============== 事件处理方法 ===============

/**
 * 分页相关事件处理
 */
const handleSizeChange = (val: number) => {
  pageSize.value = val
  currentPage.value = 1
  loadMediaList() // 重新加载数据
}

const handleCurrentChange = (val: number) => {
  currentPage.value = val
  loadMediaList() // 重新加载数据
}

/**
 * 表格选择事件处理
 */
const handleSelectionChange = (selection) => {
  selectedItems.value = selection
}

/**
 * 文件上传事件处理
 */
const handleFileSelected = (file: UploadFile, fileList: UploadFile[]) => {
  selectedFiles.value = fileList
}

/**
 * 文件移除事件处理
 */
const handleFileRemove = (file: UploadFile, fileList: UploadFile[]) => {
  selectedFiles.value = fileList
}

/**
 * 取消上传
 */
const cancelUpload = () => {
  // 清空文件列表
  selectedFiles.value = []
  // 重置上传组件
  if (uploadRef.value) {
    uploadRef.value.clearFiles()
  }
  showUploadDialog.value = false
}

/**
 * 确认上传文件
 */
const confirmUpload = async () => {
  if (!selectedFiles.value.length) return

  const loadingInstance = ElLoading.service({
    lock: true,
    text: '上传中...',
    background: 'rgba(0, 0, 0, 0.7)',
  })

  try {
    // 准备文件列表
    const rawFiles = selectedFiles.value.map((file) => file.raw)
    // 保存文件数量用于显示成功消息
    const fileCount = selectedFiles.value.length

    // 调用上传API
    const res = await sourceApi.uploadSource(rawFiles, uploadGroupId.value)

    // 先重新加载媒体列表，获取最新的总数
    await loadMediaList()

    // 然后更新分组数据，包括未分组文件计数
    await loadGroups()

    // 刷新分类数量
    if (sidebarFilterRef.value) {
      try {
        await sidebarFilterRef.value.loadTypeCounts()
      } catch (error) {
        console.error('刷新分类数量失败:', error)
      }
    }

    // 清空文件列表
    selectedFiles.value = []
    // 重置上传组件
    if (uploadRef.value) {
      uploadRef.value.clearFiles()
    }

    // 关闭对话框
    ElMessage.success(`成功上传 ${fileCount} 个文件`)
    showUploadDialog.value = false
  } catch (error) {
    console.error('上传失败:', error)
    ElMessage.error('文件上传失败，请重试')
  } finally {
    loadingInstance.close()
  }
}

/**
 * 文件删除事件处理
 */
const handleDeleteMedia = async (item: MediaFile) => {
  try {
    await ElMessageBox.confirm('确定要删除这个文件吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    })

    await sourceApi.deleteSource(item.id)

    // 先重新加载媒体列表，获取最新的总数
    await loadMediaList()

    // 然后更新分组数据，包括未分组文件计数
    await loadGroups()

    // 刷新分类数量
    if (sidebarFilterRef.value) {
      try {
        await sidebarFilterRef.value.loadTypeCounts()
      } catch (error) {
        console.error('刷新分类数量失败:', error)
      }
    }
    ElMessage.success('删除成功')
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除失败:', error)
      ElMessage.error('删除失败，请重试')
    }
  }
}

/**
 * 批量删除事件处理
 */
const handleBatchDelete = async () => {
  if (!selectedItems.value.length) return

  try {
    await ElMessageBox.confirm(
      `确定要删除选中的 ${selectedItems.value.length} 个文件吗？`,
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      },
    )

    const ids = selectedItems.value.map((item) => item.id)
    await sourceApi.deleteSource(ids)

    // 先重新加载媒体列表，获取最新的总数
    await loadMediaList()

    // 然后更新分组数据，包括未分组文件计数
    await loadGroups()

    // 刷新分类数量
    if (sidebarFilterRef.value) {
      try {
        await sidebarFilterRef.value.loadTypeCounts()
      } catch (error) {
        console.error('刷新分类数量失败:', error)
      }
    }
    selectedItems.value = []
    ElMessage.success('删除成功')
  } catch (error) {
    if (error !== 'cancel') {
      console.error('批量删除失败:', error)
      ElMessage.error('批量删除失败，请重试')
    }
  }
}

/**
 * 批量移动事件处理
 */
const handleBatchMove = async () => {
  if (!selectedItems.value.length) return

  // 检查是否来自同一分组
  const groupIds = new Set(
    selectedItems.value.map((item) =>
      item.groupId !== null && item.groupId !== undefined ? String(item.groupId) : '-1',
    ),
  )

  if (groupIds.size > 1) {
    ElMessage.error('只能对同一分组的文件进行批量移动操作！')
    return
  }

  currentMoveItem.value = null
  // 设置当前分组ID为选中项的分组ID
  const currentGroupId =
    selectedItems.value[0].groupId !== null && selectedItems.value[0].groupId !== undefined
      ? String(selectedItems.value[0].groupId)
      : '-1'
  targetGroupId.value = currentGroupId
  console.log('批量移动设置目标分组ID:', targetGroupId.value, typeof targetGroupId.value)
  showMoveGroupDialog.value = true
}

/**
 * 添加分组事件处理
 */
const handleAddGroup = () => {
  // 重置表单
  newGroupForm.value = {
    name: '',
    description: '',
  }
  // 显示对话框
  showAddGroupDialog.value = true

  // 下一轮DOM更新后聚焦到输入框
  nextTick(() => {
    addGroupFormRef.value?.resetFields()
  })
}

/**
 * 提交添加分组表单
 */
const submitAddGroup = async () => {
  if (!addGroupFormRef.value) return

  await addGroupFormRef.value.validate(async (valid, fields) => {
    if (valid) {
      try {
        await sourceApi.createGroup(newGroupForm.value.name, newGroupForm.value.description || '')
        await loadGroups()
        showAddGroupDialog.value = false
        ElMessage.success('创建成功')
      } catch (error) {
        console.error('创建分组失败:', error)
        ElMessage.error('创建分组失败，请重试')
      }
    }
  })
}

/**
 * 复制链接事件处理
 */
const handleCopyLink = async (item: MediaFile) => {
  try {
    // 直接复制URL而不是Markdown格式
    const url = item.url
    const result = await copyToClipboard(url)

    if (result) {
      ElMessage.success('链接已复制到剪贴板')
    } else {
      ElMessage.error('复制失败，请手动复制')
    }
  } catch (error) {
    console.error('复制失败:', error)
    ElMessage.error('复制失败，请手动复制')
  }
}

/**
 * 图片预览事件处理
 */
const handleImagePreview = (item: MediaFile) => {
  if (item.type === 'image') {
    event?.stopPropagation()
  }
}

/**
 * 项目点击事件处理
 */
const handleItemClick = (item: MediaFile) => {
  if (item.type === 'image') {
    handleImagePreview(item)
  } else if (item.type === 'document') {
    // 处理文档点击
    if (item.url && item.url !== '#') {
      // 如果URL有效，则在新窗口打开
      window.open(item.url, '_blank')
    } else {
      // 如果URL无效，显示提示
      ElMessage.info('该文档暂不支持在线预览')
    }
  }
}

/**
 * 处理类型变更
 */
const handleTypeChange = (type) => {
  activeType.value = type
  currentPage.value = 1 // 切换类型时重置页码
  loadMediaList()
}

/**
 * 处理分组变更
 */
const handleGroupChange = (groupId) => {
  activeGroup.value = String(groupId)
  loadMediaList()
}

/**
 * 处理排序变更
 */
const handleSortChange = (sort) => {
  sortBy.value = sort
  // 需要重新加载数据，因为排序现在由后端处理
  loadMediaList()
}

/**
 * 搜索面板相关事件处理
 */
const handleResetSearch = () => {
  searchKeyword.value = ''
  activeType.value = 'all'
  sortBy.value = 'time'
  loadMediaList()
}

const handleApplySearch = (form: any) => {
  searchKeyword.value = form.keyword
  activeType.value = form.type
  sortBy.value = form.sortBy
  currentPage.value = 1 // 应用筛选时重置页码
  loadMediaList()
}

/**
 * 移动媒体事件处理
 */
const handleMoveMedia = (item) => {
  currentMoveItem.value = item
  // 确保设置正确的分组ID，统一转换为字符串类型
  targetGroupId.value =
    item.groupId !== null && item.groupId !== undefined ? String(item.groupId) : '-1'
  console.log(
    '设置目标分组ID:',
    targetGroupId.value,
    typeof targetGroupId.value,
    '原始值:',
    item.groupId,
    typeof item.groupId,
  )
  showMoveGroupDialog.value = true
}

// 添加一个检查分组选择状态的方法，用于调试
const checkGroupSelection = () => {
  console.log('当前选中分组ID:', targetGroupId.value, typeof targetGroupId.value)
  console.log(
    '所有分组:',
    mediaGroups.value.map((g) => ({ id: g.id, type: typeof g.id })),
  )
}

/**
 * 移动分组对话框配置
 */
const onMoveDialogOpen = () => {
  // 确保targetGroupId是字符串类型
  if (typeof targetGroupId.value !== 'string') {
    targetGroupId.value = String(targetGroupId.value)
  }
  console.log('对话框打开时分组ID:', targetGroupId.value, typeof targetGroupId.value)
  // 延迟检查选择状态
  setTimeout(checkGroupSelection, 100)
}

/**
 * 确认移动到分组
 */
const confirmMoveToGroup = async () => {
  try {
    // 确保目标分组ID是字符串类型
    const numericTargetGroupId = String(targetGroupId.value)

    // 单个文件移动
    if (currentMoveItem.value) {
      // 获取当前分组ID
      const currentGroupId =
        currentMoveItem.value.groupId !== null && currentMoveItem.value.groupId !== undefined
          ? String(currentMoveItem.value.groupId)
          : '-1'

      // 如果目标分组与当前分组相同，则无需移动
      if (currentGroupId === numericTargetGroupId) {
        ElMessage.info('文件已在该分组中')
        showMoveGroupDialog.value = false
        currentMoveItem.value = null
        return
      }

      // 单个文件移动，使用统一的moveToGroup方法
      await sourceApi.moveToGroup(currentMoveItem.value.id, numericTargetGroupId)

      // 先重新加载媒体列表，获取最新的总数和文件分布
      await loadMediaList()

      // 然后更新分组数据，包括未分组文件计数
      await loadGroups()

      ElMessage.success('移动成功')
    }
    // 批量移动
    else if (selectedItems.value.length > 0) {
      // 获取当前分组ID
      const currentGroupId =
        selectedItems.value[0].groupId !== null && selectedItems.value[0].groupId !== undefined
          ? String(selectedItems.value[0].groupId)
          : '-1'

      // 如果目标分组与当前分组相同，则无需移动
      if (currentGroupId === numericTargetGroupId) {
        ElMessage.info('文件已在该分组中')
        showMoveGroupDialog.value = false
        selectedItems.value = []
        return
      }

      // 批量移动，使用统一的moveToGroup方法
      const ids = selectedItems.value.map((item) => item.id)
      await sourceApi.moveToGroup(ids, numericTargetGroupId)

      // 先重新加载媒体列表，获取最新的总数和文件分布
      await loadMediaList()

      // 然后更新分组数据，包括未分组文件计数
      await loadGroups()

      selectedItems.value = []
      ElMessage.success('批量移动成功')
    }

    showMoveGroupDialog.value = false
    currentMoveItem.value = null
  } catch (error) {
    console.error('移动失败:', error)
    ElMessage.error('移动失败，请重试')
  }
}

/**
 * 编辑分组事件处理
 */
const handleEditGroup = (group, event) => {
  event?.stopPropagation()
  currentEditGroup.value = { ...group }
  showEditGroupDialog.value = true
}

/**
 * 确认编辑分组
 */
const confirmEditGroup = async () => {
  if (!currentEditGroup.value) return

  try {
    await sourceApi.updateGroup(
      currentEditGroup.value.id,
      currentEditGroup.value.name,
      currentEditGroup.value.description || '',
    )
    await loadGroups()
    ElMessage.success('更新成功')
    showEditGroupDialog.value = false
  } catch (error) {
    console.error('更新分组失败:', error)
    ElMessage.error('更新分组失败，请重试')
  }
}

/**
 * 删除分组
 */
const handleDeleteGroup = async () => {
  if (!currentEditGroup.value) return

  try {
    await ElMessageBox.confirm(
      `确定要删除"${currentEditGroup.value.name}"分组吗？该分组下的文件将被移至未分组。`,
      '删除分组',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      },
    )

    await sourceApi.deleteGroup(currentEditGroup.value.id)
    await loadGroups()
    ElMessage.success('删除成功')
    showEditGroupDialog.value = false
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除分组失败:', error)
      ElMessage.error('删除分组失败，请重试')
    }
  }
}

/**
 * 搜索处理
 */
const debounceSearch = useDebounce(() => {
  currentPage.value = 1
  loadMediaList()
}, 500)

/**
 * 重置关键词
 */
const handleResetKeyword = () => {
  searchKeyword.value = ''
  loadMediaList()
}

// 在onMounted中初始化数据
onMounted(async () => {
  await loadData()
})

/**
 * 加载数据
 */
const loading = ref(false)
const loadData = async () => {
  try {
    loading.value = true

    // 先加载媒体列表，获取总文件数
    await loadMediaList()

    // 然后加载分组数据，这样可以确保计算未分组数量时总数是准确的
    await loadGroups()

    // 刷新分类数量
    if (sidebarFilterRef.value) {
      try {
        await sidebarFilterRef.value.loadTypeCounts()
      } catch (error) {
        console.error('刷新分类数量失败:', error)
      }
    }
  } catch (error) {
    console.error('加载数据失败:', error)
    ElMessage.error('数据加载失败，请重试')
  } finally {
    loading.value = false
  }
}

/**
 * 加载分组数据
 */
const loadGroups = async () => {
  try {
    const res = await sourceApi.getGroups()
    if (res && Array.isArray(res)) {
      // 确保有未分组选项
      const hasUngrouped = res.some((group) => String(group.id) === '-1')

      // 处理分组数据，确保id是字符串类型
      const processedGroups = res.map((group) => ({
        ...group,
        id: String(group.id),
      }))

      if (!hasUngrouped) {
        // 尝试获取API提供的总数
        let ungroupedCount = 0
        try {
          const countRes = await sourceApi.getSourceCount()
          if (countRes) {
            // 计算API返回的所有文件总数
            const apiTotalCount =
              (countRes.imageCount || 0) + (countRes.docCount || 0) + (countRes.otherCount || 0)

            // 计算其他所有分组的文件总数（仅考虑有fileNum的分组）
            const otherGroupsFileCount = processedGroups.reduce((total, group) => {
              return total + (typeof group.fileNum === 'number' ? group.fileNum : 0)
            }, 0)

            // 未分组数量 = API总数 - 其他分组总数
            ungroupedCount = Math.max(0, apiTotalCount - otherGroupsFileCount)
            console.log('[未分组数量计算]', {
              apiTotalCount,
              otherGroupsFileCount,
              ungroupedCount,
            })
          }
        } catch (error) {
          console.error('获取文件统计数据失败', error)
          // 获取失败时使用后端的记录总数
          ungroupedCount = Math.max(0, totalCount.value - 0)
        }

        // 添加未分组选项
        processedGroups.unshift({
          id: '-1',
          name: '未分组',
          description: '默认分组，未分类的文件',
          fileNum: ungroupedCount,
        })
      }

      mediaGroups.value = processedGroups
      console.log(
        '加载的分组数据:',
        mediaGroups.value.map((g) => ({ id: g.id, type: typeof g.id })),
      )
    }
  } catch (error) {
    console.error('加载分组失败:', error)
    ElMessage.error('加载分组失败')
  }
}

/**
 * 加载媒体列表
 */
const loadMediaList = async () => {
  try {
    const params = {
      pageNum: currentPage.value,
      pageSize: pageSize.value,
      name: searchKeyword.value, // 将keyword改为name以匹配后端参数
      fileType: activeType.value === 'all' ? null : activeType.value, // 直接使用activeType的值，因为SidebarFilter已经提供了正确的值
      groupId: activeGroup.value !== null ? String(activeGroup.value) : null, // 转为字符串类型
      sortField: mapSortField(sortBy.value), // 用于后端排序字段
      sortOrder: sortOrder.value, // 用于后端排序顺序
    }

    const res = await sourceApi.getList(params)
    if (res && res.records) {
      mediaList.value = res.records.map((item) => ({
        ...item,
        // 确保groupId是字符串类型，如果为null或undefined则设为-1
        groupId: item.groupId === null || item.groupId === undefined ? '-1' : String(item.groupId),
        // 确保前端显示正确的类型
        type: getTypeDisplayFromCode(item.fileType),
        // 格式化大小和更新时间以便显示
        size: formatFileSize(item.fileSize),
        // 确保时间字段有效：优先使用updateOn，然后是createOn，最后是当前时间
        updateTime: normalizeTimestamp(item.updateOn || item.createOn),
      }))
      // 更新总记录数
      totalCount.value = res.total || 0

      // 刷新分类数量
      if (sidebarFilterRef.value) {
        try {
          await sidebarFilterRef.value.loadTypeCounts()
        } catch (error) {
          console.error('刷新分类数量失败:', error)
        }
      }
    }
  } catch (error) {
    console.error('加载素材列表失败:', error)
    ElMessage.error('加载素材列表失败')
  }
}

/**
 * 规范化时间戳，确保时间戳是有效的且不会导致展示问题
 * @param {string|null} timestamp 时间戳字符串
 * @returns {string} 处理后的时间戳
 */
const normalizeTimestamp = (timestamp) => {
  if (!timestamp) return new Date().toISOString()

  // 尝试解析时间戳
  const date = new Date(timestamp)

  // 检查是否为有效日期
  if (isNaN(date.getTime())) {
    return new Date().toISOString()
  }

  // 如果日期在未来（可能是因为服务器与客户端时间不同步）
  // 将其设置为当前时间
  const now = new Date()
  if (date > now) {
    return now.toISOString()
  }

  return date.toISOString()
}

/**
 * 将前端类型映射为后端fileType
 * @param {string} type 前端类型 'image', 'document', 'other'
 * @returns {string} 后端fileType '0', '1', '2'
 */
const mapTypeToFileType = (type) => {
  switch (type) {
    case 'image':
      return '0'
    case 'document':
      return '1'
    case 'other':
      return '2'
    default:
      return null
  }
}

/**
 * 将前端排序字段映射为后端sortField
 * @param {string} sort 前端排序 'time', 'name', 'size'
 * @returns {string} 后端sortField 'updateOn', 'name', 'fileSize'
 */
const mapSortField = (sort) => {
  switch (sort) {
    case 'time':
      return 'updateOn'
    case 'name':
      return 'name'
    case 'size':
      return 'fileSize'
    default:
      return 'updateOn'
  }
}

/**
 * 格式化文件大小
 * @param {number} size 文件大小（字节）
 * @returns {string} 格式化后的大小
 */
const formatFileSize = (size) => {
  if (!size) return '0 B'

  const units = ['B', 'KB', 'MB', 'GB', 'TB']
  let i = 0
  while (size >= 1024 && i < units.length - 1) {
    size /= 1024
    i++
  }

  return `${size.toFixed(1)} ${units[i]}`
}

/**
 * 根据类型编码获取显示类型
 * @param {string|number} typeCode 类型编码 '0'-图片, '1'-文档, '2'-其他
 * @returns {string} 显示类型 'image', 'document', 'other'
 */
const getTypeDisplayFromCode = (typeCode) => {
  switch (String(typeCode)) {
    case '0':
      return 'image'
    case '1':
      return 'document'
    case '2':
      return 'other'
    default:
      return 'other'
  }
}

/**
 * 获取分组的文件数量
 */
const getGroupCount = (groupId) => {
  // 将输入的groupId转换为字符串，确保类型一致
  const numericGroupId = String(groupId)

  // 查找对应分组
  const group = mediaGroups.value.find((g) => String(g.id) === numericGroupId)

  // 如果存在分组并且有fileNum字段，优先使用后端提供的数量
  if (group && typeof group.fileNum === 'number') {
    return group.fileNum
  }

  // 降级方案：手动计算文件数量
  return numericGroupId === '-1'
    ? mediaList.value.filter((item) => !item.groupId || String(item.groupId) === '-1').length
    : mediaList.value.filter((item) => String(item.groupId) === numericGroupId).length
}

// 添加表单验证规则
const rules = {
  name: [
    { required: true, message: '请输入分组名称', trigger: 'blur' },
    { min: 1, max: 20, message: '长度在 1 到 20 个字符', trigger: 'blur' },
  ],
  description: [{ max: 100, message: '描述不能超过100个字符', trigger: 'blur' }],
}

// 可选：排序顺序切换按钮方法
const toggleSortOrder = () => {
  sortOrder.value = sortOrder.value === 'ascend' ? 'descend' : 'ascend'
  loadMediaList()
}
</script>

<style lang="scss" scoped>
// 导入主题变量和混合器
@use '@/assets/styles/theme/base.scss' as *;
@use '@/assets/styles/mixins.scss' as *;
@use 'sass:color';

/**
 * 素材库管理组件样式
 * 使用BEM命名规范与主题变量
 */
.source-manager {
  height: 100%;
  background-color: $bg-light;
  display: flex;
  flex-direction: column;

  /**
   * 页面头部样式 - 移除背景和卡片效果
   */
  :deep(.page-header) {
    padding: 6px 24px 6px;
    margin-bottom: 1px;

    .page-header__title-area {
      padding-left: 10px;
    }
  }

  /**
   * 头部操作区
   */
  .header-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    height: 40px;

    /**
     * 搜索框
     */
    .search-box {
      width: 220px;

      :deep(.el-input__wrapper) {
        border-radius: $radius-medium;
        background-color: $bg-base;
        box-shadow: none;
        padding-left: 8px;

        &.is-focus {
          box-shadow: 0 0 0 1px $color-primary inset;
        }

        &:hover {
          background-color: color.adjust($bg-base, $lightness: -2%);
        }

        .el-input__prefix {
          font-size: 14px;
          color: $text-secondary;
        }
      }

      :deep(.el-input__inner) {
        font-size: $font-size-small;
        height: 32px;
        color: $text-regular;

        &::placeholder {
          color: $text-secondary;
        }
      }
    }

    /**
     * 视图切换按钮组
     */
    .view-switch {
      .el-radio-group {
        background: $bg-light;
        padding: 2px;
        border-radius: $radius-medium;
        display: flex;
        gap: 2px;

        .el-radio-button {
          :deep(.el-radio-button__inner) {
            border: none;
            background: transparent;
            padding: 6px 12px;
            height: 32px;
            border-radius: $radius-medium;
            @include transition(all);
            display: flex;
            align-items: center;
            justify-content: center;

            &:hover {
              color: $color-primary;
              background: rgba($color-primary, 0.1);
            }
          }

          &.is-active {
            :deep(.el-radio-button__inner) {
              background: $bg-base;
              color: $color-primary;
              font-weight: 500;
              @include box-shadow('light');
            }
          }
        }
      }
    }

    /**
     * 上传按钮
     */
    .upload-btn {
      height: 32px;
      padding: 0 16px;
      border-radius: $radius-medium;
      @include transition(all);
      font-size: $font-size-small;

      .el-icon {
        margin-right: 4px;
        font-size: 14px;
      }
    }
  }

  /**
   * 主内容区域
   */
  .main-content {
    flex: 1;
    min-height: 0;
    padding: 10px;
    display: flex;
    gap: 24px;
    max-width: 1600px;
    margin: 0 auto;
    width: 100%;

    /**
     * 左侧边栏
     */
    .sidebar {
      width: 240px;
      background: $bg-base;
      padding: 16px;
      border-radius: $radius-medium;
      height: 100%;
      overflow: auto;
      @include custom-scrollbar;
    }

    /**
     * 右侧内容区
     */
    .content {
      flex: 1;
      min-width: 0;
      background: $bg-base;
      border-radius: $radius-medium;
      display: flex;
      flex-direction: column;
      height: 100%;

      .el-scrollbar {
        flex: 1;
        height: 0;
      }

      /**
       * 分页器
       */
      .pagination {
        height: 56px;
        padding: 0 16px;
        border-top: 1px solid $border-light;
        @include flex-center;

        :deep(.el-pagination) {
          button {
            border-radius: $radius-base;
            margin: 0 4px;

            &:hover {
              background: $bg-light;
            }
          }

          .el-pager li {
            border-radius: $radius-base;
            margin: 0 4px;
            color: $text-primary;
            font-weight: 500;
            background-color: $bg-light;

            &:hover {
              background: rgba($color-primary, 0.1);
              color: $color-primary;
            }

            &.is-active {
              background: $color-primary;
              color: white;
              font-weight: 600;
            }
          }

          .el-pagination__total,
          .el-pagination__sizes {
            margin-right: 16px;
          }

          .btn-prev,
          .btn-next {
            color: $text-primary;
            font-weight: 500;
            background-color: $bg-light;

            &:disabled {
              color: $text-placeholder;
              background-color: transparent;
            }
          }

          .el-pagination__jump {
            margin-left: 16px;
            color: $text-regular;

            .el-input__inner {
              text-align: center;
              color: $text-primary;
            }
          }
        }
      }
    }
  }
}

/**
 * 上传对话框样式
 */
.upload-dialog {
  .upload-area {
    width: 100%;
    margin-bottom: 20px;

    :deep(.el-upload-dragger) {
      width: 100%;
      padding: 30px 0;
      @include transition(all);

      &:hover {
        border-color: $color-primary;
      }
    }

    .upload-icon {
      font-size: 48px;
      color: $color-primary;
      margin-bottom: 16px;
    }

    .upload-text {
      p {
        font-size: $font-size-body;
        margin: 0;
        color: $text-regular;

        &.upload-tip {
          margin-top: 8px;
          font-size: $font-size-small;
          color: $text-secondary;
        }
      }
    }
  }

  .upload-options {
    margin-top: 24px;

    .option-item {
      display: flex;
      align-items: center;
      margin-bottom: 16px;

      .option-label {
        width: 80px;
        flex-shrink: 0;
        font-size: $font-size-body;
        color: $text-regular;
      }

      .el-select {
        flex: 1;
      }
    }
  }
}

/**
 * 移动分组对话框样式
 */
.move-group-dialog {
  .dialog-tip {
    margin-top: 0;
    margin-bottom: 16px;
    color: $text-regular;
  }

  .group-grid {
    width: 100%;
  }

  .group-list {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
    width: 100%;

    :deep(.el-radio) {
      height: auto;
      margin: 0;
      padding: 0;
    }

    .group-item {
      margin-right: 0;
      width: 100%;
      padding: 0;
      height: auto;

      .group-content {
        padding: 12px;
        border-radius: $radius-medium;
        @include transition(all);
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-left: 8px;
        width: calc(100% - 8px);
        border: 1px solid transparent;

        &:hover {
          background-color: $bg-light;
          border-color: $border-light;
        }
      }

      &.is-checked {
        .group-content {
          background-color: rgba($color-primary, 0.05);
          border-color: $color-primary;
        }
      }

      .group-info {
        display: flex;
        align-items: center;
        max-width: calc(100% - 40px);
        overflow: hidden;
        flex: 1;

        .el-icon {
          flex-shrink: 0;
          margin-right: 6px;
          font-size: 16px;
          color: $text-regular;
        }

        .group-name {
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
          font-size: $font-size-small;
          color: $text-primary;
        }

        .info-icon {
          flex-shrink: 0;
          margin-left: 4px;
          font-size: 14px;
          color: $text-secondary;
        }
      }

      .group-actions {
        display: flex;
        align-items: center;
        flex-shrink: 0;
        width: 40px;
        justify-content: flex-end;

        .count {
          min-width: 30px;
          text-align: center;
          font-size: $font-size-small;
          color: $text-secondary;
          background: $bg-light;
          padding: 1px 6px;
          border-radius: $radius-round;
          @include transition(all);
        }
      }
    }
  }
}

/**
 * 加载状态样式
 */
.loading-container,
.empty-container {
  padding: 100px 0;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;

  .loading-icon {
    font-size: 40px;
    color: $color-primary;
    animation: loading-rotate 1.5s linear infinite;
  }

  @keyframes loading-rotate {
    0% {
      transform: rotate(0);
    }
    100% {
      transform: rotate(360deg);
    }
  }
}

/**
 * 编辑分组对话框样式
 */
.edit-group-dialog,
.add-group-dialog {
  .el-form {
    width: 100%;
  }
}

.dialog-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;

  .delete-btn {
    margin-right: auto;
  }
}

:deep(.custom-dialog) {
  .el-message-box__message {
    width: 100%;

    p {
      margin-top: 0;
    }

    .el-form {
      width: 100%;
    }
  }
}
</style>
